//
//  IMAPIManager.m
//  DualMediationSDK
//
//  Created by YeJary on 2025/6/23.
//

#import "IMAPIManager.h"
#import "../../Utils/Network/IMNetworkUtils.h"
#import "../../Utils/Logger/IMLogUtils.h"
#import "../Login/IMLoginService.h"
#import "../../Utils/Device/IMKeychainUUIDManager.h"

// 常量定义
NSString * const IMLoginStatusKey = @"loginStatus";
NSString * const IMLoginUserUUIDKey = @"userUUID";
NSString * const IMLoginTimestampKey = @"loginTimestamp";
NSString * const IMLoginErrorKey = @"loginError";

// 通知名称
NSString * const IMLoginStatusDidChangeNotification = @"IMLoginStatusDidChangeNotification";

@interface IMAPIManager ()

@property (nonatomic, strong) IMAPIConfig *apiConfig;
@property (nonatomic, strong) IMLoginService *loginService;
@property (nonatomic, assign) BOOL isInitialized;

@end

@implementation IMAPIManager

static IMAPIManager *_sharedManager = nil;
static dispatch_once_t _onceToken;

+ (instancetype)sharedManager {
    dispatch_once(&_onceToken, ^{
        _sharedManager = [[IMAPIManager alloc] init];
    });
    return _sharedManager;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        [IMLogUtils info:IMLogTagSDKInit format:@"Creating IMAPIManager instance"];
        [self setupManager];
    }
    return self;
}

- (void)setupManager {
    [IMLogUtils debug:IMLogTagSDKInit format:@"Setting up API manager components"];
    
    // 创建API配置
    _apiConfig = [IMAPIConfig sharedConfig];
    [IMLogUtils debug:IMLogTagSDKInit format:@"API config instance created"];
    
    // 创建服务实例
    _loginService = [IMLoginService sharedService];
    [IMLogUtils debug:IMLogTagSDKInit format:@"Login service instance created"];
    
    _isInitialized = NO;
    
    [IMLogUtils info:IMLogTagSDKInit format:@"API manager setup completed"];
}

#pragma mark - 初始化配置

- (void)configureWithBaseURL:(NSString *)baseURL appID:(NSString *)appID {
    [IMLogUtils info:IMLogTagSDKInit format:@"Configuring API manager with simple parameters"];
    [self configureWithBaseURL:baseURL
                  debugBaseURL:nil
                         appID:appID
                   isDebugMode:NO];
}

- (void)configureWithBaseURL:(NSString *)baseURL
                debugBaseURL:(NSString *)debugBaseURL
                       appID:(NSString *)appID
                 isDebugMode:(BOOL)isDebugMode {
    
    [IMLogUtils info:IMLogTagSDKInit format:@"=== API Manager Configuration Start ==="];
    [IMLogUtils info:IMLogTagSDKInit format:@"Production URL: %@", baseURL];
    [IMLogUtils info:IMLogTagSDKInit format:@"Debug URL: %@", debugBaseURL ?: @"None"];
    [IMLogUtils info:IMLogTagSDKInit format:@"App ID: %@", appID];
    [IMLogUtils info:IMLogTagSDKInit format:@"Debug Mode: %@", isDebugMode ? @"YES" : @"NO"];
    
    if (!baseURL || baseURL.length == 0) {
        [IMLogUtils error:IMLogTagSDKInit format:@"Invalid base URL provided"];
        return;
    }
    
    if (!appID || appID.length == 0) {
        [IMLogUtils error:IMLogTagSDKInit format:@"Invalid app ID provided"];
        return;
    }
    
    // 配置API设置
    [IMLogUtils debug:IMLogTagSDKInit format:@"Configuring production environment"];
    [self.apiConfig configureProductionWithBaseURL:baseURL appID:appID];
    
    if (debugBaseURL) {
        [IMLogUtils debug:IMLogTagSDKInit format:@"Configuring debug environment"];
        [self.apiConfig configureDebugWithBaseURL:debugBaseURL appID:appID];
    }
    
    if (isDebugMode) {
        [IMLogUtils debug:IMLogTagSDKInit format:@"Switching to debug environment"];
        [self.apiConfig switchToDebug];
    } else {
        [IMLogUtils debug:IMLogTagSDKInit format:@"Using production environment"];
        [self.apiConfig switchToProduction];
    }
    
    // 配置网络工具
    [self configureNetworkUtils];
    
    _isInitialized = YES;
    
    [IMLogUtils info:IMLogTagSDKInit format:@"=== API Manager Configuration Complete ==="];
    [IMLogUtils info:IMLogTagSDKInit format:@"Current environment: %@", self.apiConfig.currentBaseURL];
}

- (void)configureNetworkUtils {
    [IMLogUtils debug:IMLogTagNetwork format:@"Configuring network utilities"];
    
    // 创建网络配置
    IMNetworkConfig *networkConfig = [IMNetworkConfig defaultConfig];
    networkConfig.baseURL = self.apiConfig.currentBaseURL;
    networkConfig.timeoutInterval = self.apiConfig.defaultTimeoutInterval;
    networkConfig.maxRetryCount = self.apiConfig.defaultRetryCount;
    networkConfig.retryInterval = self.apiConfig.retryInterval;
    networkConfig.defaultHeaders = self.apiConfig.defaultHeaders;
    
    [IMLogUtils verbose:IMLogTagNetwork format:@"Network config - URL: %@, Timeout: %.1fs, Retry: %ld", 
     networkConfig.baseURL, networkConfig.timeoutInterval, (long)networkConfig.maxRetryCount];
    
    // 根据调试模式调整配置
    if (self.apiConfig.isDebugMode) {
        [IMLogUtils debug:IMLogTagNetwork format:@"Debug mode enabled - enhancing network logging"];
        networkConfig.enableLogging = YES;
        networkConfig.timeoutInterval = MAX(networkConfig.timeoutInterval, 60.0);
    } else {
        [IMLogUtils debug:IMLogTagNetwork format:@"Production mode - minimal network logging"];
        networkConfig.enableLogging = NO;
    }
    
    // 初始化网络工具
    [IMNetworkUtils initWithConfig:networkConfig];
    
    [IMLogUtils info:IMLogTagNetwork format:@"Network utilities configured successfully"];
}

#pragma mark - 环境切换

- (void)switchToProduction {
    [IMLogUtils info:IMLogTagGeneral format:@"Switching to production environment"];
    
    if (!self.isInitialized) {
        [IMLogUtils error:IMLogTagGeneral format:@"Cannot switch environment - API manager not initialized"];
        return;
    }
    
    NSString *previousURL = self.apiConfig.currentBaseURL;
    [self.apiConfig switchToProduction];
    [self configureNetworkUtils];
    
    [IMLogUtils info:IMLogTagGeneral format:@"Environment switched: %@ -> %@", previousURL, self.apiConfig.currentBaseURL];
}

- (void)switchToDebug {
    [IMLogUtils info:IMLogTagGeneral format:@"Switching to debug environment"];
    
    if (!self.isInitialized) {
        [IMLogUtils error:IMLogTagGeneral format:@"Cannot switch environment - API manager not initialized"];
        return;
    }
    
    NSString *previousURL = self.apiConfig.currentBaseURL;
    [self.apiConfig switchToDebug];
    [self configureNetworkUtils];
    
    [IMLogUtils info:IMLogTagGeneral format:@"Environment switched: %@ -> %@", previousURL, self.apiConfig.currentBaseURL];
}

#pragma mark - 实现头文件中声明的方法

- (void)configureWithConfig:(IMAPIConfig *)config {
    [IMLogUtils info:IMLogTagSDKInit format:@"Configuring API manager with config object"];
    
    if (!config) {
        [IMLogUtils error:IMLogTagSDKInit format:@"Cannot configure - config object is nil"];
        return;
    }
    
    self.apiConfig = config;
    [self configureNetworkUtils];
    _isInitialized = YES;
    
    [IMLogUtils info:IMLogTagSDKInit format:@"API manager configured with external config - URL: %@", config.currentBaseURL];
}

- (IMAPIConfig *)currentConfig {
    [IMLogUtils verbose:IMLogTagGeneral format:@"Retrieving current API config"];
    return self.apiConfig;
}

- (BOOL)isConfigured {
    [IMLogUtils verbose:IMLogTagGeneral format:@"API manager configuration status: %@", self.isInitialized ? @"YES" : @"NO"];
    return self.isInitialized;
}

- (void)setRequestTimeout:(NSTimeInterval)timeout {
    [IMLogUtils info:IMLogTagNetwork format:@"Setting request timeout: %.1f seconds", timeout];
    self.apiConfig.defaultTimeoutInterval = timeout;
    [self configureNetworkUtils];
}

- (void)setMaxRetryCount:(NSInteger)maxRetryCount {
    [IMLogUtils info:IMLogTagNetwork format:@"Setting max retry count: %ld", (long)maxRetryCount];
    self.apiConfig.defaultRetryCount = maxRetryCount;
    [self configureNetworkUtils];
}

- (void)setDefaultHeaders:(NSDictionary<NSString *, NSString *> *)headers {
    [IMLogUtils info:IMLogTagNetwork format:@"Setting default headers: %@", headers.allKeys];
    self.apiConfig.defaultHeaders = [headers mutableCopy];
    [self configureNetworkUtils];
}

- (NSString *)sdkVersion {
    NSString *version = [[self class] getSDKVersion];
    [IMLogUtils verbose:IMLogTagGeneral format:@"SDK version requested: %@", version];
    return version;
}

- (BOOL)isNetworkAvailable {
    // 简单的网络可达性检查
    BOOL available = YES; // 实际实现应该使用Reachability
    [IMLogUtils verbose:IMLogTagNetwork format:@"Network availability check: %@", available ? @"Available" : @"Unavailable"];
    return available;
}

#pragma mark - 用户状态查询

- (BOOL)isUserLoggedIn {
    // 优先检查钥匙串中的UUID
    if ([IMKeychainUUIDManager hasLoginUUID]) {
        [IMLogUtils verbose:IMLogTagGeneral format:@"User login status check: Logged in (keychain UUID found)"];
        return YES;
    }
    
    // 兼容性：检查NSUserDefaults中的登录状态
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *userUUID = [defaults objectForKey:IMLoginUserUUIDKey];
    NSNumber *loginTimestamp = [defaults objectForKey:IMLoginTimestampKey];
    
    BOOL isLoggedIn = (userUUID != nil && userUUID.length > 0 && loginTimestamp != nil);
    [IMLogUtils verbose:IMLogTagGeneral format:@"User login status check: %@", isLoggedIn ? @"Logged in (UserDefaults)" : @"Not logged in"];
    
    return isLoggedIn;
}

- (nullable NSString *)getCurrentUserUUID {
    // 优先从UserDefaults获取登录成功后保存的UUID
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *loginUUID = [defaults objectForKey:IMLoginUserUUIDKey];
    
    if (loginUUID && loginUUID.length > 0) {
        [IMLogUtils verbose:IMLogTagGeneral format:@"Current user UUID from login response: %@", loginUUID];
        return loginUUID;
    }
    
    // 如果没有登录UUID，则从钥匙串获取
    NSString *keychainUUID = nil;
    if ([IMKeychainUUIDManager hasLoginUUID]) {
        keychainUUID = [IMKeychainUUIDManager getOrCreateLoginUUID];
        [IMLogUtils verbose:IMLogTagGeneral format:@"Current user UUID from keychain: %@", keychainUUID];
        return keychainUUID;
    }
    
    [IMLogUtils verbose:IMLogTagGeneral format:@"No UUID found in both login response and keychain"];
    return nil;
}

- (NSString *)getLoginStatusDescription {
    if ([self isUserLoggedIn]) {
        NSString *uuid = [self getCurrentUserUUID];
        return [NSString stringWithFormat:@"已登录 (UUID: %@)", uuid];
    } else {
        return @"未登录";
    }
}

- (nullable NSDictionary *)getUserLoginInfo {
    if (![self isUserLoggedIn]) {
        return nil;
    }
    
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSMutableDictionary *loginInfo = [NSMutableDictionary dictionary];
    
    NSString *userUUID = [defaults objectForKey:IMLoginUserUUIDKey];
    NSNumber *loginTimestamp = [defaults objectForKey:IMLoginTimestampKey];
    
    if (userUUID) {
        loginInfo[IMLoginUserUUIDKey] = userUUID;
    }
    
    if (loginTimestamp) {
        loginInfo[IMLoginTimestampKey] = loginTimestamp;
        
        // 添加可读的时间格式
        NSDate *loginDate = [NSDate dateWithTimeIntervalSince1970:loginTimestamp.doubleValue];
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
        loginInfo[@"loginDateString"] = [formatter stringFromDate:loginDate];
    }
    
    loginInfo[IMLoginStatusKey] = @(YES);
    
    return [loginInfo copy];
}

- (void)checkAndRefreshLoginWithCompletion:(void(^)(BOOL success, NSError * _Nullable error))completion {
    [IMLogUtils info:IMLogTagGeneral format:@"Checking and refreshing login status"];
    
    if (![self isUserLoggedIn]) {
        [IMLogUtils info:IMLogTagGeneral format:@"User not logged in, refresh not needed"];
        if (completion) {
            completion(NO, [NSError errorWithDomain:@"IMAPIManager" 
                                               code:-2001 
                                           userInfo:@{NSLocalizedDescriptionKey: @"用户未登录"}]);
        }
        return;
    }
    
    // 这里可以添加刷新登录状态的逻辑
    // 目前简单返回当前状态
    [IMLogUtils info:IMLogTagGeneral format:@"Login status refresh completed"];
    if (completion) {
        completion(YES, nil);
    }
}

- (NSDictionary *)getEnvironmentInfo {
    NSMutableDictionary *envInfo = [NSMutableDictionary dictionary];
    
    envInfo[@"sdkVersion"] = [self sdkVersion];
    envInfo[@"isDebugMode"] = @(self.apiConfig.isDebugMode);
    envInfo[@"currentBaseURL"] = self.apiConfig.currentBaseURL ?: @"Not configured";
    envInfo[@"isInitialized"] = @(self.isInitialized);
    envInfo[@"isNetworkAvailable"] = @([self isNetworkAvailable]);
    envInfo[@"isUserLoggedIn"] = @([self isUserLoggedIn]);
    
    if ([self isUserLoggedIn]) {
        envInfo[@"currentUserUUID"] = [self getCurrentUserUUID] ?: @"Unknown";
    }
    
    return [envInfo copy];
}

#pragma mark - 登录接口

- (void)loginWithAppId:(NSString *)appId
              iosUuid:(NSString *)iosUuid
          countryCode:(NSString *)countryCode
              success:(void(^)(NSDictionary *responseData))success
              failure:(void(^)(NSError *error))failure {
    
    [IMLogUtils info:IMLogTagAPI format:@"Starting user login process"];
    
    if (!self.isInitialized) {
        NSError *error = [NSError errorWithDomain:@"IMAPIManager" 
                                             code:-3001 
                                         userInfo:@{NSLocalizedDescriptionKey: @"API管理器未初始化"}];
        [IMLogUtils error:4 format:@"Login failed: API manager not initialized"];
        if (failure) {
            failure(error);
        }
        return;
    }
    
    // 使用钥匙串中的UUID
    NSString *keychainUUID = [IMKeychainUUIDManager getOrCreateLoginUUID];
    [IMLogUtils info:IMLogTagAPI format:@"Using keychain UUID for login: %@", keychainUUID];
    
    [self.loginService loginWithAppId:appId
                              iosUuid:keychainUUID
                         countryCode:countryCode
                             success:^(IMLoginResponse *response) {
                                 [IMLogUtils info:IMLogTagAPI format:@"Login successful, saving user data"];
                                 
                                 // 注意：登录成功后，服务器返回的UUID将保存在NSUserDefaults中
                                 // 钥匙串中的UUID仅用于登录请求
                                  
                                  // 保存登录信息到本地
                                  [self saveLoginInfo:response.data];
                                  
                                  // 发送登录状态变更通知
                                  [self postLoginStatusChangeNotification:YES error:nil];
                                  
                                  // 准备返回数据
                                  NSMutableDictionary *responseData = [NSMutableDictionary dictionary];
                                  responseData[@"code"] = @(response.code);
                                  responseData[@"message"] = response.message ?: @"";
                                  
                                  if (response.data) {
                                      NSMutableDictionary *data = [NSMutableDictionary dictionary];
                                      data[@"uuid"] = response.data.uuid ?: @"";
                                      data[@"reg_ts"] = response.data.reg_ts ?: @"";
                                      responseData[@"data"] = data;
                                  }
                                  
                                  if (success) {
                                      success([responseData copy]);
                                  }
                              }
                              failure:^(NSError *error) {
                                  [IMLogUtils error:IMLogTagAPI format:@"Login failed: %@", error.localizedDescription];
                                  
                                  // 发送登录状态变更通知
                                  [self postLoginStatusChangeNotification:NO error:error];
                                  
                                  if (failure) {
                                      failure(error);
                                  }
                              }];
}

- (void)logout {
    [IMLogUtils info:IMLogTagAPI format:@"User logout initiated"];
    
    // 清除本地登录信息
    [self clearLoginInfo];
    
    // 清除钥匙串中的登录UUID
    [IMKeychainUUIDManager clearLoginUUID];
    
    // 发送登录状态变更通知
    [self postLoginStatusChangeNotification:NO error:nil];
    
    [IMLogUtils info:IMLogTagAPI format:@"User logout completed"];
}

#pragma mark - 私有方法

- (void)saveLoginInfo:(IMLoginResponseData *)loginData {
    if (!loginData) {
        [IMLogUtils warning:IMLogTagAPI format:@"Cannot save login info: data is nil"];
        return;
    }
    
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:loginData.uuid forKey:IMLoginUserUUIDKey];
    [defaults setObject:@([[NSDate date] timeIntervalSince1970]) forKey:IMLoginTimestampKey];
    [defaults synchronize];
    
    [IMLogUtils info:IMLogTagAPI format:@"Login info saved for user: %@", loginData.uuid];
}

- (void)clearLoginInfo {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults removeObjectForKey:IMLoginUserUUIDKey];
    [defaults removeObjectForKey:IMLoginTimestampKey];
    [defaults removeObjectForKey:IMLoginErrorKey];
    [defaults synchronize];
    
    [IMLogUtils info:IMLogTagAPI format:@"Login info cleared"];
}

- (void)postLoginStatusChangeNotification:(BOOL)isLoggedIn error:(NSError *)error {
    NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
    userInfo[IMLoginStatusKey] = @(isLoggedIn);
    
    if (isLoggedIn) {
        NSString *userUUID = [self getCurrentUserUUID];
        if (userUUID) {
            userInfo[IMLoginUserUUIDKey] = userUUID;
        }
        userInfo[IMLoginTimestampKey] = @([[NSDate date] timeIntervalSince1970]);
    }
    
    if (error) {
        userInfo[IMLoginErrorKey] = error;
    }
    
    [[NSNotificationCenter defaultCenter] postNotificationName:IMLoginStatusDidChangeNotification
                                                        object:self
                                                      userInfo:[userInfo copy]];
    
    [IMLogUtils debug:IMLogTagAPI format:@"Login status change notification posted: %@", isLoggedIn ? @"Logged in" : @"Logged out"];
}

#pragma mark - 工具方法

+ (NSString *)getSDKVersion {
    return @"1.0.0"; // 可以从配置文件或Info.plist读取
}

#pragma mark - Description

- (NSString *)description {
    return [NSString stringWithFormat:@"<%@: %p> initialized:%@ debugMode:%@ baseURL:%@",
            NSStringFromClass([self class]), self,
            self.isInitialized ? @"YES" : @"NO",
            self.apiConfig.isDebugMode ? @"YES" : @"NO",
            self.apiConfig.currentBaseURL];
}

@end
